#!/usr/bin/python

import sys, os, random, time
import struct
import serial
 
RELLENO=21     # 21  = 0x15 -> Relleno de 6 bits bajos de conversion
MARCA=170      # 170 = 0xAA -> Marca de final de serie
NUMCANALES=25  # Numero de canales que lee el medidor
TAMDATA=2    # Numero de bits con los que se muestran los datos
TIME_MASK=6    # Mascara de bits que define los bytes usados para definir el tiempo


fout = 0 
ser = 0
ant = 0

def EsRelleno(byte):
    return (byte & RELLENO == RELLENO)

def EsMarca(byte):
    return byte == MARCA

def analizarTime(primero):
    global ant

    strdato=ser.read(1)
    time1 = int(hex(ord(strdato)).replace('0x', ''), 16)
    strdato=ser.read(1)
    time2 = int(hex(ord(strdato)).replace('0x', ''), 16)

    resul = (time1*256+time2)*4*256
    str_resul = str(resul)

    if primero:

        #    print "time = " + resul
#        print "diff time: " + str(resul) + " - " + str(ant) + " = " + str(resul - ant)
        ant = resul

        fout.write("time= ");
        fout.write(str_resul)
        fout.write("\n");


def main(fichero):
    print "Comandos de configuracion (EXIT para finalizar)"

    global TAMDATA
    global ser
    try:
        ser = serial.Serial(fichero, 115200, parity=serial.PARITY_NONE)
    except:
        print "Error, medidor de potencia mal conectado. Asegurarse que se ha definido correctamente el nombre del puerto serie."
        exit (-1)

    cmd=""
    modo="conversacion"
    while (cmd!="exit" and cmd!="EXIT"):
        cmd = raw_input(">")

        if cmd in ["MODECONV", "modeconv"]:
            ser.write("\x55")
            modo="conversacion"
#Ignorar primer ciclo
            ser.read(NUMCANALES*TAMDATA+4)

        elif cmd in ["BITS8", "bits8"]:
            if modo == "conversacion":
                modo="configuracion" 
                ser.write("\x01")
            ser.write("\x51")
            TAMDATA=1

        elif cmd in ["BITS10", "bits10"]:
            if modo == "conversacion":
                modo="configuracion"
                ser.write("\x01")
            ser.write("\xA1")
            TAMDATA=2

        elif cmd in ["SETTIME", "settime"]:
            if modo == "conversacion":
                modo="configuracion"
                ser.write("\x01")
            ser.write("\xA9")

            tmask = 0
            while (tmask < 1 or tmask > 15):
                tmask = raw_input("Mascara de bits (entero entre 1 y 15):")
            
            data = struct.pack('b', tmask)    
            ser.write(data)
            TIME_MASK=tmask

        elif cmd in ["GETTIME", "gettime"]:
            if modo == "conversacion":
                modo="configuracion"
                ser.write("\x01")

            ser.write("\x59")

            total = 0
            for i in [3,2,1,0,8,8,8,8,9,9,9,9]:
                time=ser.read(1)
                dato = int(hex(ord(time)).replace('0x', ''), 16)
                print "time", str(i), ": ", str(dato) 
                total = total * 256 + dato
            print "total: " + str(total*4)
                
        elif cmd in ["SETCHANNEL", "setchannel"]:
            if modo == "conversacion":
                modo="configuracion"
                ser.write("\x01")
            ser.write("\xAA")

            for i in [3,2,1,0]:
                channel_mask = -1
                while (channel_mask < 0 or channel_mask > 255):
                    if i == 3:
                        time_mask = raw_input("Mascara de bits para el canal 24:")
                    else:
                        time_mask = raw_input("Mascara de bits para los canales(%d:%d):", i*8, i*8+7)
                data = struct.pack('b', time_mask)    
                ser.write(data)
            

        elif cmd in ["GETCHANNEL", "getchannel"]:
            if modo == "conversacion":
                modo="configuracion"
                ser.write("\x01")
            ser.write("\x50")

            channel = -1
            while (channel < 0 or channel > 24):
                time_mask = raw_input("Canal a convertir (entero del 0 al 24):")
            
            data = struct.pack('b', time_mask)    
            ser.write(data)

            strdato = ser.read(1)
            byte1 = int(hex(ord(strdato)).replace('0x', ''), 16)
            strdato = ser.read(1)
            byte2 = int(hex(ord(strdato)).replace('0x', ''), 16)
            dato = byte1 * 4 + (byte2 - RELLENO) / 64
            dato = float (dato)
            print dato


        elif cmd in ["GETCONFIG", "getconfig"]:
            if modo == "conversacion":
                modo="configuracion"
                ser.write("\x01")
            ser.write("\x5A")
            datos = [0,0,0,0]
            for i in [3,2,1,0]:
                strdato = ser.read(1)
                dato = int(hex(ord(strdato)).replace('0x', ''), 16)
                datos[i]=dato
            print datos
            mostrar_binario(datos)
                
            
        elif cmd in ["exit", "EXIT"]:
            if modo == "configuracion":
                option = raw_input("Modo configuracion activo desea salir igualmente?(s/N)")
                if option not in ["s", "S"]:
                    print "Volviendo a los Comandos de configuracion (EXIT para finalizar)"
                    cmd=""
        else:
            print "Comando incorrecto"

    print "Configuracion finalizada."

    global fout
    fout=open('datos.txt', 'w')

#Situarse a la primera marca
    strdato=ser.read(1)

    ant_marca = False;
    encontrado = False;

#Buscar dos marcas consecutivas
    while strdato!='' and not (encontrado):
        dato = int(hex(ord(strdato)).replace('0x', ''), 16)

#	print "dato=", hex(dato)

        if EsMarca(dato):
            print "es marca"
            if ant_marca:
                encontrado = True
            else:
                ant_marca = True
        else:
            print "no es marca"
            ant_marca = False
        
        strdato=ser.read(1)


#Recorrer toda una traza de datos para comprobar que el formato se ajusta con lo que espera el usuario

    for i in range (NUMCANALES*2):
      dato = int(hex(ord(strdato)).replace('0x', ''), 16)

      if i % 2 == 1:
          if not EsRelleno(dato):
              print "ERRROR, en el formato de los datos obtenidos. Comprobar numero de lineas"
              exit(-1)
      strdato=ser.read(1)

#Saltarnos el time y las marcas
    analizarTime(False)      
    strdato=ser.read(1)
    strdato=ser.read(1)


#Leer y escribir en el nuevo fichero
    cont=0;
    iterations = 5000;
    while strdato!='' and iterations>0:
        byte1 = int(hex(ord(strdato)).replace('0x', ''), 16)
        strdato = ser.read(1)
        byte2 = int(hex(ord(strdato)).replace('0x', ''), 16)
        dato = byte1 * 4 + (byte2 - RELLENO) / 64
        dato = float (dato)
        fout.write(str(dato) + "\t")
        cont+=2
        iterations-=1

        if cont == (NUMCANALES * TAMDATA):
#        if cont == (NUMCANALES * B):
            #Saltarnos el time y las marcas
            cont = 0
            analizarTime(True)

#marcas

            ant_marca = False;
            encontrado = True;

            strdato=ser.read(1)
            dato = int(hex(ord(strdato)).replace('0x', ''), 16)
            if not(EsMarca(dato)):
                print "ERROR, no es marca1"
                print "En el dato: " + str((5000 - iterations)/25)
                encontrado = False

            strdato=ser.read(1)
            dato = int(hex(ord(strdato)).replace('0x', ''), 16)
            if not(EsMarca(dato)):
                print "ERROR, no es marca2"
                encontrado = False
            else:
                ant_marca = True


#Buscar dos marcas consecutivas
            while strdato!='' and not (encontrado):
                strdato=ser.read(1)
                dato = int(hex(ord(strdato)).replace('0x', ''), 16)

                if EsMarca(dato):
                    print "es marca"
                    if ant_marca:
                        encontrado = True
                    else:
                        ant_marca = True
                else:
                    print "."
                    ant_marca = False
        
        strdato = ser.read(1)

    ser.close()
    fout.close()
    return 0
 
if __name__ == '__main__':
    if len(sys.argv)<2:
        print "Uso: ordenes <nombre_entrada>"
    else:
        main(sys.argv[1])
        




